package com.codebox.knowledge.rxjava.operator;

import android.widget.TextView;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * window操作符:
 * 定期将来自Observable的数据分拆成一些Observable窗口，然后发射这些窗口，而不是每次发射一项
 * <p>
 * 简单的说就是：数据源的发射方式是一个数据发射一次，而使用了window后，
 * 将收到的Observable 数据放到一块，减少发送次数。
 *
 * @author 李立
 * @date 2019/1/1
 */
public class RxJava2Window {

    private TextView mTvLog;

    public RxJava2Window(TextView textView) {
        this.mTvLog = textView;
    }

    public void testWindow() {

        mTvLog.setText("");

        Observable
                //一个按照给定的时间间隔发射整数序列的Observable
                .interval(1, TimeUnit.SECONDS)
                //取数据前10条
                .take(10)

                //不用window：会走10此onNext();
//                .subscribe(new Observer<Long>() {
//                    @Override
//                    public void onSubscribe(Disposable d) {
//                        LogUtils.d("RxJava2Window------>onSubscribe()" );
//                    }
//
//                    @Override
//                    public void onNext(Long aLong) {
//                        LogUtils.d("RxJava2Window------>accept():" + aLong);
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
//                        LogUtils.d("RxJava2Window------>onError()" + e);
//                    }
//
//                    @Override
//                    public void onComplete() {
//                        LogUtils.d("RxJava2Window------>onComplete()" );
//                    }
//                });
                //使用window 每执行一次onNext ，onNext 内部的accept方法 最多可执行5次。
                //如果不用window，会直接执行10次onNext()
                //但是onComplete方法可能会在最后一个accept方法前执行。
                .window(5, TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())  // 使用主线程更新ui,否则下文 onNext 报错
                .subscribe(new Observer<Observable<Long>>() {

                    //其中onSubscribe 首先执行（只执行一次），
                    //onComplete()最后执行（执行一次）
                    @Override
                    public void onError(Throwable e) {
//                        LogUtils.d("RxJava2Window------>onError()" + e);
                        mTvLog.append("RxJava2Window------>onError()" + "\n" + "\n");
                    }

                    @Override
                    public void onComplete() {
//                        LogUtils.d("RxJava2Window------>onComplete()");
                        mTvLog.append("RxJava2Window------>onComplete()" + "\n" + "\n");
                    }

                    @Override
                    public void onSubscribe(Disposable d) {
//                        LogUtils.d("RxJava2Window------>onSubscribe()");
                        mTvLog.append("RxJava2Window------>onSubscribe()" + "\n" + "\n");
                    }

                    @Override
                    public void onNext(Observable<Long> integerObservable) {
                        mTvLog.append("RxJava2Window------->onNext()" + "\n" + "\n");
//                        LogUtils.d("RxJava2Window------->onNext()");
                        integerObservable
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())// 使用主线程更新ui,否则下文 accept 报错
                                .subscribe(new Consumer<Long>() {
                                    @Override
                                    public void accept(Long aLong) throws Exception {
//                                LogUtils.d("RxJava2Window------>accept():" + aLong);
                                        mTvLog.append("RxJava2Window------>accept():" + aLong + "\n" + "\n");
                                    }
                                });

                    }
                });

    }
}
